package com.pay.utils;

/**
 * Created by chenweiyi on 2018/1/30.
 */
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

/**
 * 二维码工具类
 * @author chenweiyi
 *
 */
public final class ZxingUtil {
    private static String DEFAULT_FORMAT = "png";
    private ZxingUtil(){

    }

    /**
     * 生成二维码矩阵
     * @param text
     * @param size
     * @return
     * @throws WriterException
     */
    private static BitMatrix generateBitmatrix(String text,int size)throws WriterException{
        try {
            HashMap<EncodeHintType,String> hints = new HashMap<EncodeHintType,String>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix matrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, size, size,hints);
            return matrix;
        } catch (WriterException e) {
            throw e;
        }
    }

    /**
     * 解析图片中二维码的信息
     * @param image
     * @return
     * @throws Exception
     */
    private static String resolveToString(BufferedImage image)throws Exception{
        try {
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap bitmap = new BinaryBitmap(binarizer);
            HashMap<DecodeHintType,Object> hints = new HashMap<DecodeHintType,Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            Result result = new MultiFormatReader().decode(bitmap, hints);
            return result.getText().toString();
        } catch (NotFoundException e) {
            throw e;
        }
    }

    /**
     * 生成二维码到输出流
     * @param text encode的文本
     * @param size 二维码的尺寸
     * @param output 输出流
     * @return
     */
    public static void generateToStream(String text,int size,OutputStream output)throws Exception{
        try {
            String formatName = DEFAULT_FORMAT;
            BitMatrix matrix = generateBitmatrix(text, size);
            BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
            ImageIO.write(image, formatName, output);
            MatrixToImageWriter.writeToStream(matrix, formatName, output);
        } catch (WriterException e) {
            throw e;
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * 生成二维码到文件
     * @param text encode的文本
     * @param size 二维码的尺寸
     * @param file 文件
     * @throws Exception
     */
    public static void generateToFile(String text,int size,File file)throws Exception{
        try{
            String formatName = DEFAULT_FORMAT;
            BitMatrix matrix = generateBitmatrix(text, size);
            BufferedImage image = new BufferedImage(size,size,BufferedImage.TYPE_INT_RGB);
            ImageIO.write(image, formatName, file);
            MatrixToImageWriter.writeToPath(matrix, formatName, file.toPath());
        }catch(Exception e){
            throw e;
        }
    }

    /**
     * 生成二维码到路径
     * @param text encode的文本
     * @param size 二维码的尺寸
     * @param filePath 路径
     * @throws Exception
     */
    public static void generateToPath(String text,int size,String filePath)throws Exception{
        try{
            generateToFile(text, size, new File(filePath));
        }catch(Exception e){
            throw e;
        }
    }

    /**
     * 解析流中二维码的信息
     * @param input 输入流
     * @return
     * @throws Exception
     */
    public static String resolveFromStream(InputStream input)throws Exception{
        try {
            BufferedImage image = ImageIO.read(input);
            return resolveToString(image);
        } catch (IOException e) {
            throw e;
        } catch (NotFoundException e) {
            throw e;
        }
    }

    /**
     * 解析文件中二维码的信息
     * @param file 文件
     * @return
     * @throws Exception
     */
    public static String resolveFromFile(File file)throws Exception{
        try {
            BufferedImage image = ImageIO.read(file);
            return resolveToString(image);
        } catch (IOException e) {
            throw e;
        } catch (NotFoundException e) {
            throw e;
        }
    }

    /**
     * 解析路径中二维码的信息
     * @param filePath 路径
     * @return
     * @throws Exception
     */
    public static String resolveFromPath(String filePath)throws Exception{
        try {
            BufferedImage image = ImageIO.read(new File(filePath));
            return resolveToString(image);
        } catch (IOException e) {
            throw e;
        } catch (NotFoundException e) {
            throw e;
        }
    }
}